<template>
  <div class="page-container">
    <el-container>
      <el-aside class="page-aside" width="200px" v-drag v-collapse>
        <div>
          <el-input
            placeholder="字典搜索"
            v-model="filterText"
            style="padding-right: 10px;text-align: left;"
          ></el-input>
        </div>
        <div style="margin-top: 10px;">
          <el-button
            v-for="item in treeOperators"
            circle
            :key="item.id"
            :operator="item.buttonOpenMode"
            :clickTips="item.clickTips"
            :url="item.url"
            :selectedMode="item.selectedMode"
            :type="item.buttonClass"
            :title="item.name"
            @click="clickButton($event, item)"
          ><i :class="item.buttonIcon" /></el-button>
        </div>
        <div class="page-aside-grow">
          <el-tree
            ref="tree"
            class="filter-tree"
            node-key="id"
            v-loading="loading"
            element-loading-text="数据加载中..."
            :data="treeData"
            :props="treeProps"
            :highlight-current="true"
            :default-expanded-keys="treeExpand"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            @node-click="nodeClick"
          ></el-tree>
        </div>
      </el-aside>
      <el-main class="page-main">
        <!--表格内容栏-->
        <cm-table
          ref="dataTable"
          pkName="dataId"
          dataUrl="/dictionaryData/queryPage"
          :filters="filters"
          :filterFields="filterFields"
          :columns="columns"
          :defaultSort="defaultSort"
          @resetForm="resetForm"
          @handleTableOperator="handleTableOperator"
          @handleAjaxSuccess="handleAjaxSuccess"
        ></cm-table>
      </el-main>
    </el-container>

    <!--新增编辑界面-->
    <el-dialog
      v-model="dialogVisible"
      :title="operator"
      width="500px"
      :close-on-click-modal="false"
      destroy-on-close
      draggable
    >
      <el-form
        ref="dataForm"
        label-width="120px"
        label-position="right"
        :model="formData"
        :rules="rules"
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="字典名称" prop="name">
              <el-input v-model="formData.name" auto-complete="off"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="字典编码" prop="code">
              <el-input v-model="formData.code" auto-complete="off"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="字典描述" prop="description">
              <el-input v-model="formData.description" auto-complete="off"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button
          size="large"
          type="info"
          @click="dialogVisible=false"
        >取消</el-button>
        <el-button
          type="primary"
          size="large"
          :loading="editLoading"
          @click="submitForm"
        >提交</el-button>
      </template>
    </el-dialog>

    <el-dialog
      v-model="dataDialogVisible"
      :title="operator"
      width="500px"
      :close-on-click-modal="false"
      destroy-on-close
      draggable
    >
      <el-form
        ref="dataDataForm"
        label-width="120px"
        label-position="right"
        :model="dataFormData"
        :rules="dataRules"
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="数据键" prop="dicKey">
              <el-input v-model="dataFormData.dicKey" auto-complete="off"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="数据值" prop="dicValue">
              <el-input v-model="dataFormData.dicValue" auto-complete="off"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="排序" prop="ordinal">
              <el-input v-model.number="dataFormData.ordinal" auto-complete="off"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button
          size="large"
          type="info"
          @click="dataDialogVisible=false"
        >取消</el-button>
        <el-button
          type="primary"
          size="large"
          :loading="editLoading"
          @click="submitDataForm"
        >提交</el-button>
      </template>
    </el-dialog>

    <el-dialog
      :title="operator"
      width="65%"
      v-model="batchDialogVisible"
      :close-on-click-modal="false"
      class="batch-dialog"
      destroy-on-close
      draggable
    >
      <div>
        <el-form
          :model="batchFormData"
          label-width="0px"
          ref="batchDataForm"
          label-position="right"
        >
          <el-table
            class="edit-table"
            style="width:100%"
            :data="batchFormData.list"
            width="100%"
            :border="true"
          >
            <el-table-column label="数据键" header-align="center" width="200">
              <template v-slot="{ row, $index }">
                <el-form-item :prop="'list.' + $index +'.dicKey'" :rules="batchRules.dicKey">
                  <el-input v-model="row.dicKey" auto-complete="off"></el-input>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column label="数据值" header-align="center" min-width="200">
              <template v-slot="{ row, $index }">
                <el-form-item :prop="'list.' + $index +'.dicValue'" :rules="batchRules.dicValue">
                  <el-input v-model="row.dicValue" auto-complete="off"></el-input>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column label="排序" header-align="center" width="100px">
              <template v-slot="{ row, $index }">
                <el-form-item :prop="'list.' + $index +'.ordinal'" :rules="batchRules.ordinal">
                  <el-input v-model.number="row.ordinal" auto-complete="off"></el-input>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80" header-align="center" align="center">
              <template v-slot="{ row }">
                <el-button
                  @click="handleDeleteRow(row)"
                  type="danger"
                ><i class="fa fa-trash" title="删除" /></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-form>
      </div>
      <template #footer>
        <span>新增&nbsp;
          <el-input
            v-model.number="newRow"
            auto-complete="off"
            size="large"
            style="width:50px"
          ></el-input>&nbsp;行&nbsp;</span>
        <el-button size="large" type="success" @click="addNew">确定</el-button>
        <span style="padding-left:50px;">&nbsp;</span>
        <el-button
          size="large"
          type="info"
          @click="batchDialogVisible=false"
        >取消</el-button>
        <el-button
          type="primary"
          size="large"
          :loading="editLoading"
          @click="submitBatchForm"
        >提交</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import {ref, nextTick, watch} from 'vue';
import {ElMessage, ElMessageBox} from "element-plus";
import {useRoute} from 'vue-router';
import api from '@/http/api';
import {emitter} from "@/utils/bus";
import {useDictionaryStore} from '@/pinia/modules/dictionary';

const dictionaryStore = useDictionaryStore();
const route = useRoute()
const tree = ref()
const queryForm = ref()
const batchDataForm = ref()
const dataTable = ref()
const dataForm = ref()
const dataDataForm = ref()
const filterText = ref('')
const loading = ref(false)
const treeData = ref([])
const treeProps = ref({
  children: 'children',
  label: function(data) {
    return data.text +
 (data.data.code !== undefined && data.data.code != null
   ? ' [' + data.data.code + ']　' : '　')
  }
})

const treeOperators = ref([])
const treeExpand = ref([])
const filters = ref({
  dicName: '',
  dicValue: ''
})
const filterFields = ref([
  {prop: "dicName", label: "字典名称"},
  {prop: "dicValue", label: "数据值"},
])
const columns = ref([
  {prop: "dicName", label: "字典名称", minWidth: 100},
  {prop: "dicKey", label: "数据键", minWidth: 120},
  {prop: "dicValue", label: "数据值", minWidth: 140},
  {prop: "ordinal", label: "排序", minWidth: 80, type: 'number'},
  {prop: "createTime", label: "创建时间", width: 160}
])
const operator = ref('')
const dialogVisible = ref(false)
const editLoading = ref(false)
const formData = ref({})
const rules = ref({
  name: [{required: true, message: '请输入字典名称', trigger: 'blur'}],
  code: [{required: true, message: '请输入字典编码', trigger: 'blur'}]
})
const defaultSort = ref({prop: 'ordinal', order: 'ascending'})

const dataDialogVisible = ref(false)
const dataRules = ref({
  dicKey: [{required: true, message: '请输入数据键', trigger: 'blur'}],
  dicValue: [{required: true, message: '请输入数据值', trigger: 'blur'}],
  ordinal: [
    {required: true, message: '请输入排序', trigger: 'blur'},
    {type: 'number', message: '排序必须为数字', trigger: 'blur'}]
})
const dataFormData = ref({})

const newRowFlag = ref(1)
const newRow = ref(1)
const batchDialogVisible = ref(false)
const batchRules = ref({
  dicKey: [{required: true, message: '请输入数据键', trigger: 'blur'}],
  dicValue: [{required: true, message: '请输入数据值', trigger: 'blur'}],
  ordinal: [
    {required: true, message: '请输入排序', trigger: 'blur'},
    {type: 'number', message: '排序必须为数字', trigger: 'blur'}]
})
const batchFormData = ref({
  dicId: '',
  list: []
})
const menuOperators = ref(route.meta.buttons || [])

const filterNode = (value, data) => {
  if (!value) return true;
  return data.text.indexOf(value) !== -1
    || (data.data.code != null && data.data.code.indexOf(value) !== -1);
}

const nodeClick = (data) => {
  filters.value.dicId = data.id;
  dataTable.value.findPage();
}

// 重置查询表单
const resetForm = () => {
  if (queryForm.value) {
    queryForm.value.resetFields()
  }
}

const addNew = () => {
  for (let i=0;i<newRow.value;i++) {
    batchFormData.value.list.push({newRowFlag: ++newRowFlag.value});
  }
}

// 显示操作界面
const handleTableOperator = (button, row) => {
  if ((button.buttonType === 'add' || button.buttonType === 'batchAdd')
      && (filters.value.dicId === undefined
        || filters.value.dicId == null
        || filters.value.dicId === '')) {
     ElMessage.error('请先选择右侧字典！');
    return;
  }

  if (button.buttonType === 'batchAdd') {
    batchDialogVisible.value = true;
    operator.value = button.name;
    batchFormData.value = {
      dicId: filters.value.dicId,
      list: [{newRowFlag: ++newRowFlag.value}],
      button: button
    };

    nextTick(() => {
      if (batchDataForm.value) {
        batchDataForm.value.clearValidate();
      }
    });
  } else {
    dataDialogVisible.value = true;
    operator.value = button.name;
    if (button.buttonType === 'edit') {
      dataFormData.value = Object.assign({}, row, {button: button})
    } else {
      dataFormData.value = {dicId: filters.value.dicId, button: button};
    }

    nextTick(() => {
      if (dataDataForm.value)
        dataDataForm.value.clearValidate();
    });
  }
};

const handleAjaxSuccess = () => {
  dictonaryDataChange();
};

// 操作按钮点击事件
const clickButton = (event, button) => {
  event.currentTarget.blur();

  let selections = {};
  if (button.selectedMode === '2' || button.selectedMode === '4') { // 2 单选/多选
    selections = tree.value.getCurrentNode();
    if (selections === undefined || selections == null) {
      ElMessage.warning('请选择一条字典记录！');
      return;
    }
  }

  if (button.buttonType === 'delete') {
    ElMessageBox.confirm(button.clickTips, '提示', {type: 'warning'}).then(() => {
      let params = {ids: [selections.id]};

      loading.value = true
      api.post(button.dataDestUrl, params).then(res => {
        ElMessage.success(res.message);
        loadTreeData();
        loading.value = false;
      }).catch(() => {
        loading.value = false;
      });
    }).catch(() => {});
  } else {
    dialogVisible.value = true
    operator.value = '字典' + button.name
    if (button.buttonType === 'edit') {
      formData.value = Object.assign({}, selections.data, {button: button})
    } else if (button.buttonType === 'addSub') {
      formData.value = Object.assign(
        {},
        {parentId: selections.data.id},
        {button: button}
      );
    } else {
      formData.value = {button: button};
    }

    nextTick(() => {
      dataForm.value && dataForm.value.clearValidate();
    });
  }
}

// 字典保存
const submitForm = () => {
  dataForm.value && dataForm.value.validate((valid) => {
    if (valid) {
      ElMessageBox.confirm('请确认是否提交？', '提示', {type: 'info'}).then(() => {
        editLoading.value = true;
        api.post(formData.value.button.dataDestUrl, formData.value).then(res => {
          ElMessage.success(res.message);
          dialogVisible.value = false;
          dataForm.value && dataForm.value.resetFields();
          loadTreeData();
          editLoading.value = false;
        }).catch(() => {
          editLoading.value = false;
        })
      }).catch(()=>{});
    }
  });
}

const handleDeleteRow = (row) => {
  for (let i=0;i<batchFormData.value.list.length;i++) {
    if (row.newRowFlag !== undefined && row.newRowFlag === batchFormData.value.list[i].newRowFlag) {
      batchFormData.value.list.splice(i, 1);
      return;
    }
  }
}

// 字典数据保存
const submitDataForm = () => {
  dataDataForm.value.validate((valid) => {
    if (valid) {
      ElMessageBox.confirm('请确认是否提交？', '提示', {type: 'info'}).then(() => {
        editLoading.value = true
        api.post(dataFormData.value.button.dataDestUrl, dataFormData.value).then(res => {
          ElMessage.success(res.message);
          dataDialogVisible.value = false
          dataDataForm.value.resetFields()
          dataTable.value.findPage()
          editLoading.value = false;
          dictonaryDataChange();
        }).catch(() => {
          editLoading.value = false;
        });
      }).catch(()=>{});
    }
  })
}

// 字典数据批量保存
const submitBatchForm = () => {
  batchDataForm.value.validate((valid) => {
    if (valid) {
      ElMessageBox.confirm('请确认是否提交？', '提示', {type: 'info'}).then(() => {
        editLoading.value = true;
        api.post(batchFormData.value.button.dataDestUrl, batchFormData.value).then(res => {
          ElMessage.success(res.message);
          batchDialogVisible.value = false;
          batchDataForm.value.resetFields();
          dataTable.value.findPage();
          editLoading.value = false;
          dictonaryDataChange();
        }).catch(() => {
          editLoading.value = false;
        })
      }).catch(()=>{});
    }
  });
}

const loadTreeData = () => {
  // 获取本页的操作按钮
  treeOperators.value = menuOperators.value.filter(item => item.buttonLevel === '03');
  loading.value = true;
  api.post(route.meta.url).then(res => {
    let node = tree.value.getCurrentNode();
    if (node !== undefined && node != null) {
      treeExpand.value = [node.id, node.data.parentId, filters.value.dicId || 0];
    } else {
      treeExpand.value = [filters.value.dicId || 0];
    }
    treeData.value = res.data.children;
    nextTick(function(){
      tree.value.setCurrentKey(filters.value.dicId || 0);
    });
    loading.value = false;
  }).catch(e => {
    console.log(e)
    loading.value = false;
  });
}

const dictonaryDataChange = () => {
  dictionaryStore.clearDictionary();
  emitter.emit('dictionary.change');
};

loadTreeData();

watch(() => filterText.value, val => {
  tree.value.filter(val);
})
</script>